home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2008 September
/
PCWorld_2008-09_cd.bin
/
v cisle
/
sadanastroju
/
lightning-0.8-tb-win.xpi
/
chrome
/
calendar.jar
/
content
/
calendar
/
calendar-unifinder.js
< prev
next >
Wrap
Text File
|
2008-02-19
|
32KB
|
950 lines
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OEone Calendar Code, released October 31st, 2001.
*
* The Initial Developer of the Original Code is
* OEone Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Garth Smedley <garths@oeone.com>
* Mike Potter <mikep@oeone.com>
* Chris Charabaruk <coldacid@meldstar.com>
* Colin Phillips <colinp@oeone.com>
* ArentJan Banck <ajbanck@planet.nl>
* Eric Belhaire <eric.belhaire@ief.u-psud.fr>
* Matthew Willis <mattwillis@gmail.com>
* Michiel van Leeuwen <mvl@exedo.nl>
* Joey Minta <jminta@gmail.com>
* Dan Mosedale <dan.mosedale@oracle.com>
* Michael Buettner <michael.buettner@sun.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* U N I F I N D E R
*
* This is a hacked in interface to the unifinder. We will need to
* improve this to make it usable in general.
*/
var kEventStatusOrder = ["TENTATIVE", "CONFIRMED", "CANCELLED"];
// Set this to true when the calendar event tree is clicked to allow for
// multiple selection
var gCalendarEventTreeClicked = false;
// Store the start and enddate, because the providers can't be trusted when
// dealing with all-day events. So we need to filter later. See bug 306157
var gStartDate;
var gEndDate;
var kDefaultTimezone;
var gUnifinderNeedsRefresh = true;
function isUnifinderHidden() {
return document.getElementById("bottom-events-box").hidden;
}
// Extra check to see if the events are in the daterange. Some providers
// are broken when looking at all-day events.
function fixAlldayDates(aItem) {
// Using .compare on the views start and end, not on the events dates,
// because .compare uses the timezone of the datetime it is called on.
// The view's timezone is what is important here.
return ((!gEndDate || gEndDate.compare(aItem.startDate) >= 0) &&
(!gStartDate || gStartDate.compare(aItem.endDate) < 0));
}
/**
* Observer for the calendar event data source. This keeps the unifinder
* display up to date when the calendar event data is changed
*/
var unifinderObserver = {
mInBatch: false,
QueryInterface: function uO_QueryInterface (aIID) {
if (!aIID.equals(Components.interfaces.nsISupports) &&
!aIID.equals(Components.interfaces.calICompositeObserver) &&
!aIID.equals(Components.interfaces.calIObserver)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
// calIObserver:
onStartBatch: function uO_onStartBatch() {
this.mInBatch = true;
},
onEndBatch: function uO_onEndBatch() {
this.mInBatch = false;
refreshEventTree();
},
onLoad: function uO_onLoad() {
if (isUnifinderHidden() && !gUnifinderNeedsRefresh) {
// If the unifinder is hidden, all further item operations might
// produce invalid entries in the unifinder. From now on, ignore
// those operations and refresh as soon as the unifinder is shown
// again.
gUnifinderNeedsRefresh = true;
unifinderTreeView.clearItems();
}
if (!this.mInBatch) {
refreshEventTree();
}
},
onAddItem: function uO_onAddItem(aItem) {
if (isEvent(aItem) &&
!this.mInBatch &&
!gUnifinderNeedsRefresh &&
isItemInFilter(aItem)) {
this.addItemToTree(aItem);
}
},
onModifyItem: function uO_onModifyItem(aNewItem, aOldItem) {
this.onDeleteItem(aOldItem);
this.onAddItem(aNewItem);
},
onDeleteItem: function uO_onDeleteItem(aDeletedItem) {
if (isEvent(aDeletedItem) && !this.mInBatch && !gUnifinderNeedsRefresh) {
this.removeItemFromTree(aDeletedItem);
}
},
// It is safe to call these for any event. The functions will determine
// whether or not anything actually needs to be done to the tree
addItemToTree: function uO_addItemToTree(aItem) {
var items;
if (gStartDate && gEndDate) {
items = aItem.getOccurrencesBetween(gStartDate, gEndDate, {});
} else {
items = [aItem];
}
unifinderTreeView.addItems(items.filter(fixAlldayDates));
},
removeItemFromTree: function uO_removeItemFromTree(aItem) {
var items;
if (gStartDate && gEndDate && (aItem.parentItem == aItem)) {
items = aItem.getOccurrencesBetween(gStartDate, gEndDate, {});
} else {
items = [aItem];
}
unifinderTreeView.removeItems(items.filter(fixAlldayDates));
},
onError: function uO_onError(aErrNo, aMessage) {},
onPropertyChanged: function uO_onPropertyChanged(aCalendar, aName, aValue, aOldValue) {},
onPropertyDeleting: function uO_onPropertyDeleting(aCalendar, aName) {},
// calICompositeObserver:
onCalendarAdded: function uO_onCalendarAdded(aDeletedItem) {
if (!this.mInBatch) {
refreshEventTree();
}
},
onCalendarRemoved: function uO_onCalendarRemoved(aDeletedItem) {
// TODO only remove such items that belong to the calendar
if (!this.mInBatch) {
refreshEventTree();
}
},
onDefaultCalendarChanged: function uO_onDefaultCalendarChanged(aNewDefaultCalendar) {}
};
/**
* Called when the calendar is loaded
*/
function prepareCalendarUnifinder() {
// Only load once
window.removeEventListener("load", prepareCalendarUnifinder, false);
var unifinderTree = document.getElementById("unifinder-search-results-tree");
// Check if this is not the hidden window, which has no UI elements
if (unifinderTree) {
// set up our calendar event observer
var ccalendar = getCompositeCalendar();
ccalendar.addObserver(unifinderObserver);
kDefaultTimezone = calendarDefaultTimezone();
// Set up the unifinder views.
unifinderTreeView.treeElement = unifinderTree;
unifinderTree.view = unifinderTreeView;
// Listen for changes in the selected day, so we can update if need be
var viewDeck = getViewDeck();
viewDeck.addEventListener("dayselect", unifinderDaySelect, false);
viewDeck.addEventListener("itemselect", unifinderItemSelect, true);
// Set up sortDirection and sortActive, in case it persisted
var active = document.getElementById("unifinder-search-results-tree-cols")
.getElementsByAttribute("sortActive", "true");
if (active.length > 0) {
unifinderTreeView.selectedColumn = active[0].id;
unifinderTreeView.sortDirection = active[0].getAttribute("sortDirection");
}
// Display something upon first load. onLoad doesn't work properly for
// observers
if (!isUnifinderHidden()) {
gUnifinderNeedsRefresh = false;
refreshEventTree();
}
}
}
/**
* Called when the calendar is unloaded
*/
function finishCalendarUnifinder() {
var ccalendar = getCompositeCalendar();
ccalendar.removeObserver(unifinderObserver);
var viewDeck = getViewDeck();
if (viewDeck) {
viewDeck.removeEventListener("dayselect", unifinderDaySelect, false);
viewDeck.removeEventListener("itemselect", unifinderItemSelect, true);
}
}
/**
* Event listeners for dayselect and itemselect events
*/
function unifinderDaySelect() {
var filterList = document.getElementById("event-filter-menulist");
if (filterList.selectedItem.value == "current") {
refreshEventTree();
}
}
function unifinderItemSelect(aEvent) {
unifinderTreeView.setSelectedItems(aEvent.detail);
}
/**
* Helper function to display event datetimes in the unifinder
*/
function formatUnifinderEventDateTime(aDatetime) {
var dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
.getService(Components.interfaces.calIDateTimeFormatter);
return dateFormatter.formatDateTime(aDatetime.getInTimezone(kDefaultTimezone));
}
/**
* This is called from the unifinder when a key is pressed in the search field
*/
var gSearchTimeout = null;
function searchKeyPress(searchTextItem, event) {
// 13 == return
if (event && event.keyCode == 13) {
clearSearchTimer();
refreshEventTree();
return;
}
// Always clear the old one first
clearSearchTimer();
// Make a new timer
gSearchTimeout = setTimeout("refreshEventTree()", 400);
}
function clearSearchTimer() {
if (gSearchTimeout) {
clearTimeout(gSearchTimeout);
gSearchTimeout = null;
}
}
/**
* Unifinder event handlers (click,select,etc)
*/
function unifinderDoubleClick(event) {
// We only care about button 0 (left click) events
if (event.button != 0) {
return;
}
// find event by id
var calendarEvent = unifinderTreeView.getItemFromEvent(event);
if (calendarEvent != null) {
modifyEventWithDialog(getOccurrenceOrParent(calendarEvent));
} else {
createEventWithDialog();
}
}
function unifinderSelect(event) {
var tree = unifinderTreeView.treeElement;
if (!tree.view.selection || tree.view.selection.getRangeCount() == 0) {
return;
}
var selectedItems = [];
gCalendarEventTreeClicked = true;
// Get the selected events from the tree
var start = {};
var end = {};
var numRanges = tree.view.selection.getRangeCount();
for (var t = 0; t < numRanges; t++) {
tree.view.selection.getRangeAt(t, start, end);
for (var v = start.value; v <= end.value; v++) {
try {
selectedItems.push(unifinderTreeView.getItemAt(v));
} catch (e) {
WARN("Error getting Event from row: " + e + "\n");
}
}
}
if (selectedItems.length == 1) {
// Go to the day of the selected item in the current view.
currentView().goToDay(selectedItems[0].startDate);
}
// Set up the selected items in the view. Pass in true, so we don't end
// up in a circular loop
currentView().setSelectedItems(selectedItems.length, selectedItems, true);
onSelectionChanged({detail: selectedItems});
}
function unifinderKeyPress(aEvent) {
const kKE = Components.interfaces.nsIDOMKeyEvent;
switch (aEvent.keyCode) {
case 13:
// Enter, edit the event
editSelectedEvents();
break;
case kKE.DOM_VK_BACK_SPACE:
case kKE.DOM_VK_DELETE:
deleteSelectedEvents();
break;
}
}
/**
* Tree controller for unifinder search results
*/
var unifinderTreeView = {
tree: null,
treeElement: null,
doingSelection: false,
/**
* Event functions
*/
eventArray: [],
eventIndexMap: {},
addItems: function uTV_addItems(aItemArray, aDontSort) {
this.eventArray = this.eventArray.concat(aItemArray);
if (this.tree) {
var newCount = this.eventArray.length - aItemArray.length - 1;
this.tree.rowCountChanged(newCount, aItemArray.length);
}
if (aDontSort) {
this.calculateIndexMap();
} else {
this.sortItems();
}
},
removeItems: function uTV_removeItems(aItemArray) {
for each (var item in aItemArray) {
var row = this.getItemRow(item);
if (row > -1) {
this.eventArray.splice(row, 1);
if (this.tree) {
this.tree.rowCountChanged(row, -1);
}
}
}
this.calculateIndexMap();
},
clearItems: function uTV_clearItems() {
var oldCount = this.eventArray.length;
this.eventArray = [];
if (this.tree) {
this.tree.rowCountChanged(0, -oldCount);
}
this.calculateIndexMap();
},
setItems: function uTV_setItems(aItemArray, aDontSort) {
var oldCount = this.eventArray.length;
this.eventArray = aItemArray.slice(0);
if (this.tree) {
this.tree.rowCountChanged(0, (this.eventArray.length - oldCount));
}
if (aDontSort) {
//this.calculateIndexMap();
} else {
this.sortItems();
}
},
calculateIndexMap: function uTV_calculateIndexMap() {
this.eventIndexMap = {};
for (var i = 0 ; i < this.eventArray.length; i++) {
this.eventIndexMap[this.eventArray[i].hashId] = i;
}
if (this.tree) {
this.tree.invalidate();
}
},
sortItems: function uTV_sortItems() {
// Get a current locale string collator for compareEvents
if (!this.localeCollator) {
var localeService =
Components
.classes["@mozilla.org/intl/nslocaleservice;1"]
.getService(Components.interfaces.nsILocaleService);
this.localeCollator =
Components
.classes["@mozilla.org/intl/collation-factory;1"]
.getService(Components.interfaces.nsICollationFactory)
.CreateCollation(localeService.getApplicationLocale());
}
this.sortStartedTime = new Date().getTime(); // for null/0 dates in sort
// sort (key,item) entries
var entries = this.eventArray.map(sortEntry);
entries.sort(sortEntryComparer(this));
this.eventArray = entries.map(sortEntryItem);
this.calculateIndexMap();
},
getItemRow: function uTV_getItemRow(item) {
if (this.eventIndexMap[item.hashId] === undefined) {
return -1;
}
return this.eventIndexMap[item.hashId];
},
getItemAt: function uTV_getItemAt(aRow) {
return this.eventArray[aRow];
},
/**
* Get the calendar item from the given event
*/
getItemFromEvent: function uTV_getItemFromEvent(event) {
var row = this.tree.getRowAt(event.clientX, event.clientY);
if (row > -1) {
return this.getItemAt(row);
}
return null;
},
setSelectedItems: function uTV_setSelectedItems(aItemArray) {
if (this.doingSelection || !this.tree) {
return;
}
this.doingSelection = true;
// If no items were passed, get the selected items from the view.
aItemArray = aItemArray || currentView().getSelectedItems({});
/**
* The following is a brutal hack, caused by
* http://lxr.mozilla.org/mozilla1.0/source/layout/xul/base/src/tree/src/nsTreeSelection.cpp#555
* and described in bug 168211
* http://bugzilla.mozilla.org/show_bug.cgi?id=168211
* Do NOT remove anything in the next 3 lines, or the selection in the tree will not work.
*/
this.treeElement.onselect = null;
this.treeElement.removeEventListener("select", unifinderSelect, true);
this.tree.view.selection.selectEventsSuppressed = true;
this.tree.view.selection.clearSelection();
if (aItemArray && aItemArray.length == 1) {
// If only one item is selected, scroll to it
var rowToScrollTo = this.getItemRow(aItemArray[0]);
if (rowToScrollTo > -1) {
this.tree.ensureRowIsVisible(rowToScrollTo);
this.tree.view.selection.select(rowToScrollTo);
}
} else if (aItemArray && aItemArray.length > 1) {
// If there is more than one item, just select them all.
for (var i in aItemArray) {
var row = this.getItemRow(aItemArray[i]);
this.tree.view.selection.rangedSelect(row, row, true);
}
}
// This needs to be in a setTimeout
setTimeout("unifinderTreeView.resetAllowSelection()", 1);
},
resetAllowSelection: function uTV_resetAllowSelection() {
if (!this.tree) {
return;
}
/**
* Do not change anything in the following lines, they are needed as
* described in the selection observer above
*/
this.doingSelection = false;
this.tree.view.selection.selectEventsSuppressed = false;
this.treeElement.addEventListener("select", unifinderSelect, true);
},
/**
* Tree View Implementation
*/
get rowCount uTV_getRowCount() {
return this.eventArray.length;
},
getRowProperties: function uTV_getRowProperties() {},
getCellProperties: function uTV_getCellProperties() {},
getColumnProperties: function uTV_getColumnProperties() {},
isContainer: function uTV_isContainer() {
return false;
},
isContainerOpen: function uTV_isContainerOpen(aRow) {
return false;
},
isContainerEmpty: function uTV_isContainerEmpty(aRow) {
return false;
},
isSeparator: function uTV_isSeparator(aRow) {
return false;
},
isSorted: function uTV_isSorted(aRow) {
return false;
},
canDrop: function uTV_canDrop(aRow, aOrientation) {
return false;
},
drop: function uTV_drop(aRow, aOrientation) {},
getParentIndex: function uTV_getParentIndex(aRow) {
return -1;
},
hasNextSibling: function uTV_hasNextSibling(aRow, aAfterIndex) {},
getLevel: function uTV_getLevel(aRow) {
return 0;
},
getImageSrc: function uTV_getImageSrc(aRow, aOrientation) {},
getProgressMode: function uTV_getProgressMode(aRow, aCol) {},
getCellValue: function uTV_getCellValue(aRow, aCol) {
return null;
},
getCellText: function uTV_getCellText(row, column) {
calendarEvent = this.eventArray[row];
switch (column.id) {
case "unifinder-search-results-tree-col-title":
return calendarEvent.title;
case "unifinder-search-results-tree-col-startdate":
return formatUnifinderEventDateTime(calendarEvent.startDate);
case "unifinder-search-results-tree-col-enddate":
var eventEndDate = calendarEvent.endDate.clone();
// XXX reimplement
//var eventEndDate = getCurrentNextOrPreviousRecurrence(calendarEvent);
if (calendarEvent.startDate.isDate) {
// display enddate is ical enddate - 1
eventEndDate.day = eventEndDate.day - 1;
}
return formatUnifinderEventDateTime(eventEndDate);
case "unifinder-search-results-tree-col-categories":
return calendarEvent.getProperty("CATEGORIES");
case "unifinder-search-results-tree-col-location":
return calendarEvent.getProperty("LOCATION");
case "unifinder-search-results-tree-col-status":
return getEventStatusString(calendarEvent);
case "unifinder-search-results-tree-col-calendarname":
return calendarEvent.calendar.name;
default:
return false;
}
},
setTree: function uTV_setTree(tree) {
this.tree = tree;
},
toggleOpenState: function uTV_toggleOpenState(aRow) {},
cycleHeader: function uTV_cycleHeader(col) {
var sortActive = col.element.getAttribute("sortActive");
this.selectedColumn = col.id;
this.sortDirection = col.element.getAttribute("sortDirection");
if (sortActive != "true") {
var unifinder = document.getElementById("unifinder-search-results-tree");
var treeCols = unifinder.getElementsByTagName("treecol");
for (var i = 0; i < treeCols.length; i++) {
treeCols[i].removeAttribute("sortActive");
treeCols[i].removeAttribute("sortDirection");
}
this.sortDirection = "ascending";
} else {
if (!this.sortDirection || this.sortDirection == "descending") {
this.sortDirection = "ascending";
} else {
this.sortDirection = "descending";
}
}
col.element.setAttribute("sortActive", "true");
col.element.setAttribute("sortDirection", this.sortDirection);
this.sortItems();
},
isEditable: function uTV_isEditable(aRow, aCol) {
return false;
},
setCellValue: function uTV_setCellValue(aRow, aCol, aValue) {},
setCellText: function uTV_setCellText(aRow, aCol, aValue) {},
performAction: function uTV_performAction(aAction) {},
performActionOnRow: function uTV_performActionOnRow(aAction, aRow) {},
performActionOnCell: function uTV_performActionOnCell(aAction, aRow, aCol) {},
selectedColumn: null,
sortDirection: null,
sortStartedTime: new Date().getTime(), // updated just before sort
outParameter: new Object() // used to obtain dates during sort
};
function getEventSortKey(calEvent) {
switch(unifinderTreeView.selectedColumn) {
case "unifinder-search-results-tree-col-title":
return calEvent.title || "";
case "unifinder-search-results-tree-col-startdate":
return nativeTimeOrNow(calEvent.startDate);
case "unifinder-search-results-tree-col-enddate":
return nativeTimeOrNow(calEvent.endDate);
case "unifinder-search-results-tree-col-categories":
return calEvent.getProperty("CATEGORIES") || "";
case "unifinder-search-results-tree-col-location":
return calEvent.getProperty("LOCATION") || "";
case "unifinder-search-results-tree-col-status":
return calEvent.status || "";
case "unifinder-search-results-tree-col-calendarname":
return calEvent.calendar.name || "";
default:
return null;
}
}
function sortEntry (aItem) {
return {mSortKey : getEventSortKey(aItem), mItem: aItem};
}
function sortEntryItem(sortEntry) {
return sortEntry.mItem;
}
function sortEntryKey(sortEntry) {
return sortEntry.mSortKey;
}
function sortEntryComparer(unifinderTreeView) {
var modifier = (unifinderTreeView.sortDirection == "descending" ? -1 : 1);
var collator = unifinderTreeView.localeCollator;
switch (unifinderTreeView.selectedColumn) {
case "unifinder-search-results-tree-col-startdate":
case "unifinder-search-results-tree-col-enddate":
function compareTimes(sortEntryA, sortEntryB) {
var nsA = sortEntryKey(sortEntryA);
var nsB = sortEntryKey(sortEntryB);
return compareNativeTime(nsA, nsB) * modifier;
}
return compareTimes;
case "unifinder-search-results-tree-col-title":
case "unifinder-search-results-tree-col-categories":
case "unifinder-search-results-tree-col-location":
case "unifinder-search-results-tree-col-status":
case "unifinder-search-results-tree-col-calendarname":
function compareStrings(sortEntryA, sortEntryB) {
var sA = sortEntryKey(sortEntryA);
var sB = sortEntryKey(sortEntryB);
if (sA.length == 0 || sB.length == 0) {
// sort empty values to end (so when users first sort by a
// column, they can see and find the desired values in that
// column without scrolling past all the empty values).
return -(sA.length - sB.length) * modifier;
}
var comparison = collator.compareString(0, sA, sB);
return comparison * modifier;
}
return compareStrings;
default:
function compareOther(sortEntryA, sortEntryB) {
return 0;
}
return compareOther;
}
}
function compareNativeTime(a, b) {
return (a < b ? -1 :
a > b ? 1 : 0);
}
function nativeTimeOrNow(calDateTime) {
// Treat null/0 as 'now' when sort started, so incomplete tasks stay current.
// Time is computed once per sort (just before sort) so sort is stable.
if (calDateTime == null) {
return unifinderTreeView.sortStartedTime;
}
var ns = calDateTime.nativeTime;
if (ns == -62168601600000000) { // ns value for (0000/00/00 00:00:00)
return unifinderTreeView.sortStartedTime;
}
return ns;
}
function refreshEventTree() {
if (isUnifinderHidden()) {
// If the unifinder is hidden, don't refresh the events to reduce needed
// getItems calls.
return;
}
var savedThis = this;
var refreshListener = {
mEventArray: new Array(),
onOperationComplete: function rET_onOperationComplete(aCalendar,
aStatus,
aOperationType,
aId,
aDateTime) {
var refreshTreeInternalFunc = function() {
refreshEventTreeInternal(refreshListener.mEventArray);
};
setTimeout(refreshTreeInternalFunc, 0);
},
onGetResult: function rET_onGetResult(aCalendar,
aStatus,
aItemType,
aDetail,
aCount,
aItems) {
for (var i = 0; i < aCount; i++) {
refreshListener.mEventArray.push(aItems[i]);
}
}
};
var Today = new Date();
// Do this to allow all day events to show up all day long.
var StartDate = new Date(Today.getFullYear(),
Today.getMonth(),
Today.getDate(),
0, 0, 0);
var EndDate;
var ccalendar = getCompositeCalendar();
var filter = 0;
filter |= ccalendar.ITEM_FILTER_TYPE_EVENT;
var filterMenulist = document.getElementById("event-filter-menulist");
// Not all xul might be there yet...
if (!filterMenulist) {
return;
}
switch (filterMenulist.selectedItem.value) {
case "all":
StartDate = null;
EndDate = null;
break;
case "today":
EndDate = new Date(StartDate.getTime() + (1000 * 60 * 60 * 24) - 1);
break;
case "next7Days":
EndDate = new Date(StartDate.getTime() + (1000 * 60 * 60 * 24 * 8));
break;
case "next14Days":
EndDate = new Date(StartDate.getTime() + (1000 * 60 * 60 * 24 * 15));
break;
case "next31Days":
EndDate = new Date(StartDate.getTime() + (1000 * 60 * 60 * 24 * 32));
break;
case "thisCalendarMonth":
// midnight on first day of this month
var startOfMonth = new Date(Today.getFullYear(), Today.getMonth(), 1, 0, 0, 0);
// midnight on first day of next month
var startOfNextMonth = new Date(Today.getFullYear(), (Today.getMonth() + 1), 1, 0, 0, 0);
// 23:59:59 on last day of this month
EndDate = new Date(startOfNextMonth.getTime() - 1000);
StartDate = startOfMonth;
break;
case "future":
EndDate = null;
break;
case "current":
var SelectedDate = currentView().selectedDay.jsDate;
StartDate = new Date(SelectedDate.getFullYear(), SelectedDate.getMonth(), SelectedDate.getDate(), 0, 0, 0);
EndDate = new Date(StartDate.getTime() + (1000 * 60 * 60 * 24) - 1000);
break;
default:
dump("there's no case for " + filterMenulist.selectedItem.value + "\n");
EndDate = StartDate;
break;
}
gStartDate = StartDate ? jsDateToDateTime(StartDate).getInTimezone(calendarDefaultTimezone()) : null;
gEndDate = EndDate ? jsDateToDateTime(EndDate).getInTimezone(calendarDefaultTimezone()) : null;
if (StartDate && EndDate) {
filter |= ccalendar.ITEM_FILTER_CLASS_OCCURRENCES;
}
ccalendar.getItems(filter, 0, gStartDate, gEndDate, refreshListener);
}
function refreshEventTreeInternal(eventArray) {
var searchText = document.getElementById("unifinder-search-field").value;
unifinderTreeView.setItems(eventArray.filter(isItemInFilter));
// Select selected events in the tree. Not passing the argument gets the
// items from the view.
unifinderTreeView.setSelectedItems();
}
function isItemInFilter(aItem) {
var searchText = document.getElementById("unifinder-search-field")
.value.toLowerCase();
if (!searchText.length || searchText.match(/^\s*$/)) {
return true;
}
const fieldsToSearch = ["SUMMARY", "DESCRIPTION", "LOCATION", "CATEGORIES", "URL"];
if (!fixAlldayDates(aItem)) {
return false;
}
for each (var field in fieldsToSearch) {
var val = aItem.getProperty(field);
if (val && val.toLowerCase().indexOf(searchText) != -1) {
return true;
}
}
return false;
}
function focusSearch() {
document.getElementById("unifinder-search-field").focus();
}
function toggleUnifinder() {
// Toggle the elements
goToggleToolbar('bottom-events-box', 'calendar_show_unifinder_command');
goToggleToolbar('calendar-view-splitter');
unifinderTreeView.treeElement.view = unifinderTreeView;
// When the unifinder is hidden, refreshEventTree is not called. Make sure
// the event tree is refreshed now.
if (!isUnifinderHidden() && gUnifinderNeedsRefresh) {
gUnifinderNeedsRefresh = false;
refreshEventTree();
}
// Make sure the selection is correct
if (unifinderTreeView.doingSelection) {
unifinderTreeView.resetAllowSelection();
}
unifinderTreeView.setSelectedItems();
}
window.addEventListener("load", prepareCalendarUnifinder, false);
window.addEventListener("unload", finishCalendarUnifinder, false);